package com.rancedxk.monitor.api.impl;

import java.util.HashMap;
import java.util.Map;

import com.rancedxk.monitor.api.IApi;
import com.rancedxk.monitor.lib.HikvisionNetSDK;
import com.rancedxk.monitor.task.AutoStopInvoker;
import com.rancedxk.monitor.task.AutoStopTaskManager;
import com.rancedxk.monitor.utils.Kv;

public class HikvisionApi implements IApi{
	/**用户登录句柄缓存，理论上只要jvm不重启，每一个IP的命令句柄是可以保存使用的，所以此处缓存起来*/
	static Map<String,Integer> LOGIN_USER_HANDLE_CACHE = new HashMap<String,Integer>();
	
	//SDK初始化
	static{
		HikvisionNetSDK.INSTANCE.NET_DVR_Init();
	}

	@Override
	public int login(String code, String ip, String username, String password, int port) {
		if(LOGIN_USER_HANDLE_CACHE.containsKey(code)){
			return LOGIN_USER_HANDLE_CACHE.get(code);
		}
		//设置连接时间与重连时间
        HikvisionNetSDK.INSTANCE.NET_DVR_SetConnectTime(2000, 1);
        HikvisionNetSDK.INSTANCE.NET_DVR_SetReconnect(10000, true);
        //设备登录信息
        HikvisionNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HikvisionNetSDK.NET_DVR_USER_LOGIN_INFO();
        //设备信息
        HikvisionNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HikvisionNetSDK.NET_DVR_DEVICEINFO_V40();
        // 注册设备-登录参数，包括设备地址、登录用户、密码等
        m_strLoginInfo.sDeviceAddress = new byte[HikvisionNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(ip.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, ip.length());
        m_strLoginInfo.sUserName = new byte[HikvisionNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(username.getBytes(), 0, m_strLoginInfo.sUserName, 0, username.length());
        m_strLoginInfo.sPassword = new byte[HikvisionNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(password.getBytes(), 0, m_strLoginInfo.sPassword, 0, password.length());
        m_strLoginInfo.wPort = (short)port;
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是
        m_strLoginInfo.write();
        //设备信息, 输出参数
        int lUserID = HikvisionNetSDK.INSTANCE.NET_DVR_Login_V40(m_strLoginInfo,m_strDeviceInfo);
        if(lUserID< 0){
            HikvisionNetSDK.INSTANCE.NET_DVR_Cleanup();
            return -1;
        }
        //缓存
        LOGIN_USER_HANDLE_CACHE.put(code, lUserID);
        return lUserID;
	}
	
	/**
	 * 将统一命令字符转换为海康SDK能识别的int类型命令字
	 * @param commandStr 命令字符串
	 * @return int类型的命令字
	 */
	private static Map<String,Integer> COMMANDS = new HashMap<String,Integer>(){
		private static final long serialVersionUID = 1L;
		{
			put("FOCUS_NEAR", 11); //焦距放大
			put("FOCUS_FAR", 12); //焦距缩小
			put("IRIS_OPEN", 15); //光圈扩大
			put("IRIS_CLOSE", 16);//光圈缩小
			put("TILT_UP", 21);	// 云台上仰
			put("TILT_DOWN", 22);	// 云台下俯
			put("PAN_LEFT", 23);// 云台左转
			put("PAN_RIGHT", 24);	// 云台右转
			put("UP_LEFT", 25);	// 云台左转上仰
			put("UP_RIGHT", 26);	// 云台右转上仰
			put("DOWN_LEFT", 27);	// 云台左转下俯
			put("DOWN_RIGHT", 28);// 云台右转下俯
		}
	};

	@Override
	public boolean control(String code, int loginUserHandle, String command, Kv params) {
		if(AutoStopTaskManager.isContain(code)){
			AutoStopTaskManager.get(code).spirit();
		}else{
			AutoStopTaskManager.create(code, new AutoStopInvoker() {
				@Override
				public void onStart() {
					HikvisionNetSDK.INSTANCE.NET_DVR_PTZControlWithSpeed_Other(loginUserHandle, params.getInt("channel"), COMMANDS.get(command), 0, params.getInt("speed"));
				}
				
				@Override
				public void onStop() {
					HikvisionNetSDK.INSTANCE.NET_DVR_PTZControlWithSpeed_Other(loginUserHandle, params.getInt("channel"), COMMANDS.get(command), 1, params.getInt("speed"));
				}
			}, 1000);
		}
		return true;
	}
}
